<?
/////////////////////////////////////////////////////////////////////////////////////////
// Clase para Manejar Bases via PDO
/////////////////////////////////////////////////////////////////////////////////////////

class DatabasePDO
	{
		// Propiedades de la Conexion
		var $cServer = "";
		var $cDatabase = "";
		var $cUser = "";
		var $cPassword = "";
		var $oConnection = false;
		var $cSql = "";

		function beginTran()
		{
			return $this->oConnection->beginTransaction();
		}
		function commitTran()
		{
			return $this->oConnection->commit();
		}
		function rollBackTran()
		{
			return $this->oConnection->rollBack();
		}

		function getConnectionHandle()
		{
			if ( $this->oConnection == false )
			{
				$this->connect();
			}
			return $this->oConnection;
		}
		function recordset( $cSql, $nFrom = '', $nLenght = '' )
		{
			// Guara la Consulta
			$this->cSql = $cSql;
			$oRs = new RecordsetPDO ( $this );
			$bOk = $oRs->open ( $cSql, $nFrom, $nLenght );

			return $bOk ? $oRs :false;
		}
		function dbConcat( $cStrs )
		{
			$cReturn = " Concat( ";
			for ( $nContador = 0; $nContador < func_num_args();  $nContador++  )
			{
				$cReturn .= func_get_arg($nContador) . ",";
			}
			$cReturn = substr( $cReturn, 0, -1 );
			$cReturn .= ")";
			return $cReturn ;
		}
		//
		function dbLower( $cString )
		{
			return " lower($cString) ";
		}
		//
		function dbNumToStr( $cString )
		{
			return " cast($cString as char) ";
		}
		//
		function dbDate ( )
			{
				return " CURDATE() ";
			}
		//
		function dbDay ( $cField )
			{
				return " DAY( $cField ) ";
			}
		function dbMonth ( $cField )
			{
				return " MONTH( $cField ) ";
			}
		function dbYear( $cField )
			{
				return " YEAR( $cField ) ";
			}
		function dbMakeDate ( $cYear, $cMonth, $cDay )
		{
			return " Str_To_Date( Concat( $cYear, \"-\", $cMonth, \"-\", $cDay  ), \"%Y-%m-%d\" )";
		}
		//
		function dbDateToStr( $cString , $cFormato )
		{
			$cFormato = str_replace( '-', '-%' , $cFormato );
			$cFormato = str_replace( '/', '/%' , $cFormato );
			$cFormato = '%' . $cFormato;
			return " DATE_FORMAT( $cString, '$cFormato' ) ";
		}
		//
		function dbValue ( $cValor )
		{
			$cValor = trim($cValor);
			if ( $cValor === "")
			{
				$cValor = "null";
			} else
			{
				if ( ! (strpos( $cValor, "'" )  === FALSE) )
				{
					$cValor = str_replace( "'", "\'", $cValor);
				}
				$cValor = "'$cValor'";
			}
			return $cValor;
		}
		// Devuelve el numero total de Registros del Query, independientemente de que se haya puesto un TOP
		function total( $cSql, $cPatron = "FROM")
		{
			$cSql = strtoupper( $cSql);
			$cPatron = strtoupper($cPatron);
			$nPos = strpos($cSql, $cPatron );

			$cSql = "SELECT COUNT(*) " . substr( $cSql , $nPos );
			// Si Tiene Group by => Este es un Truco para obtener la cantidad de Registros
			if ( strpos($cSql, "GROUP BY" ) > 0  )
			{
			// $cSql = "SELECT COUNT(*) FROM ( $cSql ) as Tabla";
				$cSql = "SELECT COUNT(*) FROM (" . str_replace("COUNT(*)", "COUNT(*) AS NREG", $cSql) .")";
				$cSql = "$cSql  as Tabla";
			}
			$nqRows = $this->getData($cSql);
			return $nqRows;
		}
		//
		function DatabasePDO($cServer, $cDatabase = "", $cUser = "", $cPassword = "")
		{
			$this->cServer = $cServer;
			$this->cDatabase = $cDatabase;
			$this->cUser = $cUser;
			$this->cPassword = $cPassword;
			$this->oConnection = new PDO($cServer . ';' . $cDatabase, $user, $pass);
		}
		//
		function status()
		{
			return 'Server: ' . $this->cServer . ' Database: ' . $this->cDatabase . ' User: ' . $this->cUser . ' ' . ' ConId: ' . $this->oConnection ;
		}
		//
		function connect( )
		{

			$this->cServer = $cServer;
			$this->cDatabase = $cDatabase;
			$this->cUser = $cUser;
			$this->cPassword = $cPassword;
			$this->oConnection = new PDO($cServer . ';' . $cDatabase, $user, $pass);
			if ( $this->oConnection = new PDO($this->cServer) )
			// Hubo un Error !
			if ( $this->oConnection == 0 )
			{
				addMessage($cSqliteError);
				return FALSE;
			}
			return $this->oConnection;
		}
		//
		function nextKey( $cTabla, $cCampo, $cCondicion = '' )
		{
			$nCodigo = 0;
			$this->cSql = "Select Max( $cCampo ) From $cTabla ";
			if ( $cCondicion != '' )
			{
				$this->cSql .=  ' Where ' . $cCondicion;
			}
			$nCodigo = $this->getData ( $this->cSql );
			return $nCodigo == NULL ? 1: ($nCodigo + 1);
		}
		//
		function getMatrix ( $cSql, $nFrom = '', $nLenght = '' )
		{
			$aReturn = array();
			// Agrega al SQL la sentencia del Paginado
				if ( $nLenght != '' && $nFrom != -1 ) $cSql = $cSql . " LIMIT $nFrom , $nLenght ";
				$this->cSql = $cSql;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
				if ( $this->oConnection == false && !$this->connect() ) return false;
			// Loop por cada Row
				foreach ($this->oConnection->query($this->cSql) as $aRow )
				{
					$aReturn[] = $aRow;
				}
			return $aReturn;
		}
		//
		function getKeyArray( $cSql, $nFrom = '', $nLenght = '' )
		{
			$aReturn = array();
			// Agrega al SQL la sentencia del Paginado
				if ( $nLenght != '' && $nFrom != -1 ) $cSql = $cSql . " LIMIT $nFrom , $nLenght ";
				$this->cSql = $cSql;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
				if ( $this->oConnection == false && !$this->connect() ) return false;
			
			$this->oConnection->query($this->cSql, PDO::FETCH_INTO, $aRow );
			// Si es solo Codigo y Descripcion
				if ( count($aRow) == 2 )
				{
					if ( $aRow )
					{
						do
						{
							$cIndex =  "" . $aRow[0];
							$aReturn[ $cIndex ] = $aRow[1];
							$aRow = sqlite_fetch_array($this->nQuery, SQLITE_NUM );
						} while ( $aRow );
					}
				} else
				{
					// Si son Varios => Arma Array
					if ( $aRow )
					{
						do
						{
							for ( $nRow = 0; $nRow < count($aRow) ; $nRow++ )
							{
								$aReturn[$aRow[0]][] = $aRow[$nRow];
							}
							$aRow = sqlite_fetch_array($this->nQuery, SQLITE_NUM );
						} while ( $aRow );
					}
				}
			return $aReturn;
		}
		//
		function getArray( $cSql, $nFrom = '', $nLenght = '' )
		{
			$aReturn = array();
			// Agrega al SQL la sentencia del Paginado
				if ( $nLenght != '' && $nFrom != -1 ) $cSql = $cSql . " LIMIT $nFrom , $nLenght ";
				$this->cSql = $cSql;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
				if ( $this->oConnection == false && !$this->connect() ) return false;
			// Loop por cada Row
				foreach ($this->oConnection->query($this->cSql) as $aRow )
				{
					if ( count($aRow)  == 2)
					{
						$aReturn = array_merge( (array)$aReturn, (array)$aRow[0] );
					} else
					{
						$aReturn = array_merge( (array)$aReturn, (array)$aRow );
					}
				}
			return $aReturn;
		}
		//
		function getData( $cSql ) {
			$nQuery = 0;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
				if ( $this->oConnection == false && !$this->connect() ) return false;
			$this->cSql = $cSql;
			return $this->oConnection->query($this->cSql, PDO::FETCH_COLUMN, 0);
		}
		// Parametros $cTabla, $aCampos
		function insertArray( $cTabla, $aCampos )
		{
			$nContador = 0;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
				if ( $this->oConnection == 0 && !$this->connect() )
				{
					return false;
				}
			// Arma la sentencia de SQL
				foreach ( $aCampos as $cCampo => $cValor )
				{
					$cCampos .= ', '. $cCampo;
					$cValores .= ', '. $this->dbValue ( $cValor );
				}
				$cCampos = substr ( $cCampos, 1 );
				$cValores = substr ( $cValores , 1 );
				$this->cSql = "INSERT INTO $cTabla ( $cCampos ) VALUES ( $cValores )";
			// Ejecuta la Consulta
				$bExito = ($this->oConnection->exec($this->cSql )== FALSE ) ? false:  true;
				if ($bExito === false)
				{
					addMessage($this->cSql, E_ERROR);
				}
			return $bExito;
		}
		// Parametros $cTabla, { $cCampo, $cValor }
		function updateArray( $cTabla, $aCampos, $aClaves )
		{
			$nContador = 0;
			// Si no esta conectado => Intenta conectarse  y si da error => devuelve False
			if ( $this->oConnection == 0 && !$this->connect() )
			{
				return false;
			}
			foreach ( $aCampos as $cCampo => $cValor )
			{
				$cCampos .= ", $cCampo = " . $this->dbValue ( $cValor ) ;
			}
			$cCampos = substr ( $cCampos, 1 );
			foreach ( $aClaves as $cCampo => $cValor )
			{
				$cWhere .= " AND $cCampo =" . $this->dbValue ( $cValor ) ;
			}
			$cWhere = substr ( $cWhere, 4 );
			$this->cSql = "UPDATE " . $cTabla  . " SET $cCampos WHERE $cWhere ";
			$bExito = ($this->oConnection->exec( $this->cSql )== FALSE ) ? false:  true;
			if($bExito === false)
			{
				addMessage($this->cSql, E_ERROR);
			}
			return $bExito;
		}
		//
		function insert( $cTabla )
		{
			if ( $this->oConnection == 0 && !$this->connect() )
			{
				return false;
			}
			$cSql = "INSERT INTO " . $cTabla . " ( ";
			$bPrimero = true;
			for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  )
			{
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$cSql .= ", ";
				}
				$cSql .= func_get_arg($nContador);
			}
			$cSql .= ") VALUES ( ";
			$bPrimero = true;
			for ( $nContador = 2; $nContador < func_num_args();  $nContador+=2  )
			{
				$cValor = func_get_arg($nContador);
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$cSql .= ", ";
				}
				$cSql .= $this->dbValue ( $cValor );
			}
			$cSql .= ")";
			$this->cSql = $cSql;
			$bExito = ($this->oConnection->exec( $this->cSql )== FALSE ) ? false:  true;
			if($bExito === false)
			{
				addMessage($this->cSql, E_ERROR );
			}
			return $bExito;
		}
		//
		function update( $cTabla )
		{
			$nContador = 0;
			$bPrimero = true;
			$cSeparador = ", ";
			if ( $this->oConnection == 0 && !$this->connect() )
			{
				return false;
			}
			$cSql = "UPDATE " . $cTabla . " SET ";
			for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  )
			{
				if (!strcasecmp (func_get_arg($nContador), "WHERE") )
				{
					$cSql .= " WHERE " ;
					$nContador++;
					$cSeparador = " AND ";
					$bPrimero = true; // Vuelve a poner el flag del primero para saltear la primera ,
				}
				$cValor = func_get_arg($nContador + 1);
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$cSql .= $cSeparador;
				}
				$cSql .= func_get_arg($nContador) . " = " . $this->dbValue ( $cValor );
			}
			$this->cSql = $cSql;
			$bExito = ($this->oConnection->exec( $this->cSql )== FALSE ) ? false:  true;
			if($bExito === false)
			{
				addMessage($this->cSql, E_ERROR );
			}
			return $bExito;
		}
		//
		function delete( $cTabla )
		{
			$nContador = 0;
			$cValor = "";
			$bPrimero = true;
			if ( $this->oConnection == 0 && !$this->connect() )
			{
				return false;
			}
			$cSql = "DELETE FROM  " . $cTabla . " WHERE ";
			for ( $nContador = 1; $nContador < func_num_args();  $nContador+=2  )
			{
				$cValor = func_get_arg($nContador + 1);
				if ( substr(func_get_arg($nContador - 1), 0, 1) == "c" )
				{
					$cValor = "'" . $cValor . "'";
				}
				if ( $bPrimero )
				{
					$bPrimero = false;
				} else
				{
					$cSql .= " AND ";
				}
				$cSql .= func_get_arg($nContador) . " = " . $cValor;
			}
			$this->cSql = $cSql;
			$bExito = ($this->oConnection->exec($this->cSql )== FALSE ) ? false:  true;
			if($bExito === false)
			{
				addMessage($this->cSql, E_ERROR );
			}
			return $bExito;
		}
		//
		function execute( $cSql )
		{
			if ( $this->oConnection == false && !$this->connect() )
			{
				return false;
			}
			$this->cSql = $cSql;
			$bExito = ($this->oConnection->exec($this->cSql )== FALSE ) ? false:  true;
			if($bExito === false)
			{
				addMessage($this->cSql, E_ERROR );
			}
			return $bExito;
		}
	}
class RecordsetPDO
	{
		var $oConnection = 0;
		var $nQuery = 0;
		var $aFields= array();
		var $cSql = "";
		//
		function RecordsetPDO( $oConnection )
		{
			$this->oConnection = $oConnection;
		}
		function getKeyArray()
		{
			$aReturn = array();
			$aRow = array();
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			$aRow = sqlite_fetch_array($this->nQuery, SQLITE_NUM );
			// Si es solo Codigo y Descripcion
			if ( count($aRow) == 2 )
			{
				if ( $aRow )
				{
					do
					{
						$cIndex =  "" . $aRow[0];
						$aReturn[ $cIndex ] = $aRow[1];
						$aRow = sqlite_fetch_array($this->nQuery, SQLITE_NUM );
					} while ( $aRow );
				}
			} else
			{
				// Si son Varios => Arma Array
				if ( $aRow )
				{
					do
					{
						for ( $nRow = 0; $nRow < count($aRow) ; $nRow++ )
						{
							$aReturn[$aRow[0]][] = $aRow[$nRow];
						}
						$aRow = sqlite_fetch_array($this->nQuery, SQLITE_NUM );
					} while ( $aRow );
				}
			}
			//free_result ( $this->nQuery );
			return $aReturn;
		}
		function getMatrix()
		{
			$aReturn = array();
			$aRow = array();
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			while($aRow = sqlite_fetch_array( $this->nQuery ))
			{
				renameKeys( $aRow );
				$aReturn[] = $aRow;
			}
			//free_result ( $this->nQuery );
			return $aReturn;
		}
		//
		function open( $cSql, $nFrom = '', $nLenght = '' )
		{
			// Agrega al SQL la sentencia del Paginado
			if ( $nLenght != '' && $nFrom != -1 )
			{
				$cSql = $cSql . " LIMIT $nFrom , $nLenght ";
			}
			$this->cSql  = $cSql ;
      // si ya tiene un query abierto => lo cierra
			if ( $this->nQuery != 0 )
			{
				//free_result ( $this->nQuery );
			}
			$this->nQuery = sqlite_query ( $this->oConnection->getConnectionHandle(), $this->cSql );
			if( $this->nQuery === false)
			{
				addMessage($this->cSql, E_ERROR);
			}
			return $this->nQuery;
		}
		//
		function close ()
			{
			  //free_result ( $this->nQuery );
			}
		//
		function moveTo( $nRow = -1)
		{
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			if ( $nRow <= -1 )
			{
				return $this->moveNext();
			}
			if ( $nRow >= sqlite_num_rows ( $this->nQuery ) )
			{
				return false;
			}

			if ( ! sqlite_seek ( $this->nQuery, $nRow ) )
			{
				return false;
			}
			$this->aFields = sqlite_fetch_array ( $this->nQuery ) ;
			renameKeys( $this->aFields  );
			return !empty($this->aFields);
		}
		//
		function __goTo( $nRow = -1)
		{
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			if ( $nRow < 0 )
			{
				$nRow = 0;
			}
			if ( $nRow >= sqlite_num_rows ( $this->nQuery ) )
			{
				return false;
			}
			if ( ! sqlite_seek ( $this->nQuery, $nRow ) )
			{
				return false;
			}
			return true;
		}
		//
		function moveNext( $bAsociativo = 1 )
		{
			if ( $this->nQuery == 0 )
			{
				return false;
			}
			if ( $bAsociativo == 1 )
			{
				$this->aFields = sqlite_fetch_array ( $this->nQuery ) ;
				renameKeys( $this->aFields  );
			} else {
				$this->aFields = sqlite_fetch_array($this->nQuery, SQLITE_NUM ) ;
			}
			return !empty($this->aFields);
		}
		//
		function getHeaders( $cDelimitadorCampo = "'", $cSeparadorCampo = "," , $cSeparadorRegistros = "\n" )
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;
			}
			// Se mueve al Primer Registro y arma una cadena con los nombres de los campos separados por el delimitador
			$this->moveTo(0);
			$aKeys 	  = array_keys( $this->aFields  );
			$nqCampos = count($aKeys);
			for( $nCampo = 1; $nCampo < $nqCampos; $nCampo +=2 )
			{
				$cData .=  $cDelimitadorCampo . $aKeys[$nCampo] . $cDelimitadorCampo . $cSeparadorCampo;
			}
			if ( $cData  != "" )
			{
				$cData =  substr( $cData , 0, strlen($cData) - strlen($cSeparadorCampo) );
			}
			// Devuelve la cadena
			return $cData . $cSeparadorRegistros;
		}
		// Devuelve los Campos del Actual registro separados por Comas
		function getFields( $cDelimitadorCampo = "'", $cSeparadorCampo = "," )
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;
			}
			// Por cada Campo del Registro Actual, arma una cadena separada por los Delimitadores
			$cLinea = "";
			$nqCampos = count($this->aFields) / 2;
			for( $nCampo = 0; $nCampo < $nqCampos; $nCampo++ ){
				$cField  = $this->aFields[$nCampo];
				$cLinea .=  $cDelimitadorCampo . $cField . $cDelimitadorCampo . $cSeparadorCampo;
			}
			if ( $cLinea != "" )
			{
				$cLinea = substr( $cLinea , 0, strlen($cLinea) - strlen($cSeparador) );
			}
			// Devuelve la cadena
			return $cLinea;
		}
		//
		function saveQuery( $cArchivo , $cDelimitadorCampo = "'", $cSeparadorCampo = "," )
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;
			}

			$fd = fopen($cArchivo , "w");
			while ( $this->moveNext() )
			{
				fwrite($fd, $this->getFields( $cDelimitadorCampo, $cSeparadorCampo ) );
			}
			fclose($fd);
		}
		//
		function getQuery( $cDelimitadorCampo = "'", $cSeparadorCampo = "," , $cSeparadorRegistros = "\n" )
		{
			// Si No hay un Query da Error
			if ( $this->nQuery )
			{
				return false;
			}

			// Por cada Registro del Query arma una cadena con los valores separados por los delimitadores
			$cData = "";
			$nPosicion = 0;
			while ( $this->moveTo($nPosicion) )
			{
				$cData .= $this->getFields( $cDelimitadorCampo, $cSeparadorCampo ) . $cSeparadorRegistros ;
				$nPosicion++;
			}
			// Devuelve la cadena
			return $cData;
		}
		//
		function count()
		{
			if ( $this->nQuery == FALSE )
			{
				return false;
			}
			return sqlite_num_rows ( $this->nQuery );
		}
	}
?>
